package com.yc.thread;

import java.text.SimpleDateFormat;
import java.util.Date;

public class Test12_sleep_wait_lock {
    /**
     * 此方法会被 n个线程来调用,会发生争抢，同时只能一 个线程进行执行。
     * sleep()方法不会释放锁, 因此线程是按照先后顺序执行的。
     * synchronized的作用:加锁
     */

    //如果不加锁，每个对象都能运行这个函数
    public synchronized void sleepMethod() {   //这个锁指的是当前这个类的对象身上的锁
        System.out.println(printDate() + Thread.currentThread().getName() + "休眠1s");
        try {
            Thread.sleep(1000);//不会释放锁
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(printDate() + Thread.currentThread().getName() + "休眠结束");
    }

    /**
     * wait().方法会释放锁, 因此一旦 调用wait()方法就会造成其他线程运行
     *
     * @return
     */
    public synchronized void waitMethod(){
//        synchronized(this){}
        System.out.println(printDate()+Thread.currentThread().getName()+"等待一秒");
        synchronized (this){
            try {
                this.wait(1000);//释放锁  wait与sleep的区别
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(printDate()+Thread.currentThread().getName()+"等待结束");
    }
    private static String printDate() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(new Date()) + " ";
    }

    public static void main(String[] args) {
//        final Test12_sleep_wait_lock test1 = new Test12_sleep_wait_lock();//new 1次，一个对象 一把锁  如果写在for循环里面那就是是创建了5个对象，每个对象互相之间不干扰，都能执行方法，每个对象都有方法，
//        for (int i = 0; i < 5; i++) {
//            new Thread(test1::sleepMethod).start();  //5个线程抢同一个方法

///            new Thread(test1::sleepMethod).start();的解读
///            new Thread(new Runnable(){
///               @Override
///                public void run() {
///                    test1.sleepMethod();
///                }
///            }).start();
//        }
        //////////////////////////////////////////////////////////////////////
        final Test12_sleep_wait_lock test2 = new Test12_sleep_wait_lock();
        for (int i = 0; i < 5; i++) {
            new Thread(test2::waitMethod).start();
        }
    }
}